package com.gengzp.rpc.core.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.gengzp.rpc.core.RemoteTransactionalCoreFunc;
import com.gengzp.rpc.model.dto.remoteTransaction.RemoteTransactionDto;
import com.gengzp.rpc.utils.RpcJsonUtils;
import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Objects;

import static com.gengzp.rpc.constants.RemoteTransactionalConstants.REMOTE_TRANSACTION_KEY_PREFIX;

/**
 * @ClassName RemoteTransactionalCoreFuncImpl
 * @Description 远程事务核心方法实现类
 * @Author gengzp
 * @Date 2025/8/11 20:53
 */
@Component
public class RemoteTransactionalCoreFuncImpl implements RemoteTransactionalCoreFunc {

    private static final Logger logger = LoggerFactory.getLogger(RemoteTransactionalCoreFuncImpl.class);

    @Autowired
    @Qualifier("rpcRedisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    @Override
    public void saveRemoteTransaction(String requestId, String consumerServiceName, Class<?> interfaceClass,
                                      String methodName, Class<?>[] parameterTypes, Object[] params) {
        // 需要保存的已提交事务集合
        List<RemoteTransactionDto> remoteTransactions = Lists.newArrayList();

        // 先查询当前请求id中已提交的事务
        Object existRemoteTransaction = redisTemplate.opsForValue().get(REMOTE_TRANSACTION_KEY_PREFIX + requestId);
        if (Objects.nonNull(existRemoteTransaction)) {
            remoteTransactions = RpcJsonUtils.readValue((String) existRemoteTransaction, new TypeReference<>() {
            });
        }

        RemoteTransactionDto remoteTransaction = new RemoteTransactionDto();
        remoteTransaction.setRequestId(requestId);
        remoteTransaction.setConsumerServiceName(consumerServiceName);
        remoteTransaction.setInterfaceClass(interfaceClass);
        remoteTransaction.setMethodName(methodName);
        remoteTransaction.setParameterTypes(parameterTypes);
        remoteTransaction.setParams(params);
        remoteTransactions.add(remoteTransaction);
        redisTemplate.opsForValue().set(REMOTE_TRANSACTION_KEY_PREFIX + requestId,
                RpcJsonUtils.writeValueAsString(remoteTransactions));
    }

    @Override
    public List<RemoteTransactionDto> searchRemoteTransactionsByRequestId(String requestId) {
        List<RemoteTransactionDto> result = Lists.newArrayList();
        Object existRemoteTransaction = redisTemplate.opsForValue().get(REMOTE_TRANSACTION_KEY_PREFIX + requestId);
        if (Objects.nonNull(existRemoteTransaction)) {
            result = RpcJsonUtils.readValue((String) existRemoteTransaction, new TypeReference<>() {
            });
        }
        return result;
    }

}
